#include <algorithm>
#include <cstdio>
using namespace std;

const int N = 1000010;
int n, m, cnt, tot, head, sum;
int heads[N << 1], low[N << 1], dfn[N << 1], sta[N << 1], scc[N << 1];
bool ins[N << 1];

struct Edge {
	int v, nxt;
} e[10000000];
inline void add(int u, int v) {
	e[++cnt].v = v;
	e[cnt].nxt = heads[u];
	heads[u] = cnt;
}

void tarjan(int x) {
	dfn[x] = low[x] = ++tot;
	sta[++head] = x;
	ins[x] = true;
	for (int i = heads[x]; i; i = e[i].nxt) {
		int v = e[i].v;
		if (!dfn[v]) {
			tarjan(v);
			low[x] = min(low[x], low[v]);
		} else if (ins[v]) {
			low[x] = min(low[x], dfn[v]);
		}
	}
	if (dfn[x] == low[x]) {
		++sum;
		while (sta[head] != x) {
			scc[sta[head]] = sum;
			ins[sta[head]] = false;
			--head;
		}
		scc[sta[head]] = sum;
		ins[sta[head]] = false;
		--head;
	}
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("testdata.in", "r", stdin);
	freopen("testdata.out", "w", stdout);
#endif

	scanf("%d%d", &n, &m);
	int i, a, j, b;
	for (int k = 1; k <= m; ++k) {
		scanf("%d%d%d%d", &i, &a, &j, &b);
		switch (a) {
			case 1:
				switch (b) {
					case 1:
						add(i + n, j);
						add(j + n, i);
						break;
					case 0:
						add(i + n, j + n);
						add(j, i);
						break;
				}
				break;
			case 0:
				switch (b) {
					case 1:
						add(i, j);
						add(j + n, i + n);
						break;
					case 0:
						add(i, j + n);
						add(j, i + n);
						break;
				}
				break;
		}
	}
	for (int i = 1; i <= (n << 1); ++i) {
		if (!dfn[i]) tarjan(i);
	}
	for (int i = 1; i <= n; ++i) {
		if (scc[i] == scc[i + n]) {
			printf("IMPOSSIBLE\n");
			return 0;
		}
	}
	printf("POSSIBLE\n");
	for (int i = 1; i <= n; ++i) {
		if (scc[i + n] > scc[i])
			printf("1 ");
		else
			printf("0 ");
	}
	return 0;
}